#include <lc_test_thread.h>

ThreadImpl* TestThread::thread_ = nullptr;

void ThreadImpl::process() {
  for (int i = 0; i < 10; i++) {
    System::sleep(1);
    if (this->testCancellation())
      return;
  }
}

void TestThread::SetUp() {
  if (!TestThread::thread_)
    TestThread::thread_ = new ThreadImpl;
}

void TestThread::TearDown() {
  if (TestThread::thread_) {
    TestThread::thread_ = nullptr;
  }
}

void TestThread::startThread() {
  ASSERT_FALSE(thread_->isStarted());
  thread_->start();
  EXPECT_TRUE(thread_->isRunning())
      << "Thread failed to start";
}

void TestThread::joinThread() {
  ASSERT_TRUE(thread_->isStarted());
  ASSERT_EQ(Thread::STATE_JOINABLE, thread_->state());
  thread_->join();
}

TEST_F(TestThread, StartThread) {
  TestThread::startThread();
  TestThread::joinThread();
}

TEST_F(TestThread, CancelThread) {
  TestThread::startThread();
  thread_->cancel();
  System::sleep(1);
  EXPECT_FALSE(thread_->isRunning())
      << "Thread cancellation failed";
  TestThread::joinThread();
}

TEST_F(TestThread, DetachThread) {
  TestThread::startThread();
  thread_->detach();
  EXPECT_NE(Thread::STATE_JOINABLE, thread_->state())
      << "Failed to detach thread";
}
